export function resetAll() {
  const context = this
  if (context != null) {
    if (typeof context._reset === 'function') {
      context._reset()
    } else if (context.formname) {
      context.$refs[context.formname].resetFields()
    }
    if (context.$children) {
      for (let i = 0; i < context.$children.length; i++) {
        resetAll.apply(context.$children[i], arguments)
      }
    }
  }
}

export function submit() {
  const promises = []
  const context = this
  if (context != null) {
    if (context.formname) {
      promises.push(context.$refs[context.formname].validate().then(result => {
        if (context.formname && context.postdata) {
          return {
            name: context.formname,
            data: context.postdata
          }
        }

        return null
      }))
    }
    if (context.$children) {
      for (let i = 0; i < context.$children.length; i++) {
        Array.prototype.push.apply(promises, submit.apply(context.$children[i], arguments))
      }
    }
  }

  return promises
}

export function submitAll(callback, data) {
  const promises = submit.apply(this)
  Promise.all(promises).then((result) => {
    const obj = {}
    for (let i = 0; i < result.length; i++) {
      const item = result[i]
      if (item) {
        obj[item.name] = item.data
      }
    }
    callback.call(this, true, obj, data)
  }).catch((result) => {
    callback.call(this, false, {}, data)
  })
}

export function attachChange(obj) {
  if (obj.channel) {
    if (!obj.methods) {
      obj.methods = {}
    }
    const fn = obj.data
    obj.data = function() {
      const data = fn.apply(this, arguments)
      data.postdata = data.postdata || {}
      Object.assign(data.postdata, Object.assign({}, obj.channel))

      return data
    }
    for (const t in obj.channel) {
      obj.methods['on' + t + 'change'] = function(val) {
        this.postdata[t] = val
      }
    }
  }

  return obj
}

export function attachWatch(obj) {
  if (!obj.watch) {
    obj.watch = {}
  }
  if (obj.props) {
    const fn = obj.data
    obj.data = function() {
      const data = fn.apply(this, arguments)
      for (const t in obj.props) {
        data['proxy_' + t] = t.default
      }

      return data
    }
    for (const t in obj.props) {
      const watchFn = obj.watch[t]
      if (watchFn) {
        obj.watch[t] = function(val) {
          watchFn.apply(this, arguments)
          this['proxy_' + t] = val
        }
      } else {
        obj.watch[t] = function(val) {
          this['proxy_' + t] = val
        }
      }
      const proxWatchFn = obj.watch['proxy_' + t]
      if (proxWatchFn) {
        obj.watch['proxy_' + t] = function(val) {
          proxWatchFn.apply(this, arguments)
          this.$emit('on-' + t + '-change', val)
        }
      } else {
        obj.watch['proxy_' + t] = function(val) {
          this.$emit('on-' + t + '-change', val)
        }
      }
    }
  }

  return obj
}

export function attachChangeAndWatch(obj) {
  attachChange(obj)
  attachWatch(obj)

  return obj
}
